<!-- src/views/digital/csc/CscForm.vue -->
<template>
  <Dialog :title="dialogTitle" v-model="dialogVisible">
    <el-form
      ref="formRef"
      :model="formData"
      :rules="formRules"
      label-width="100px"
      v-loading="formLoading"
    >
      <!-- 佐证上传部分 -->
      <el-form-item label="佐证地址" prop="evidenceUrl">
        <el-upload
          :headers="HEADERS"
          :file-list="formData.evidenceUrl"
          class="evidence-upload"
          :action="actionUrl"
          multiple
          list-type="text"
          :on-preview="handlePreview"
          :on-remove="handleRemove"
          :before-remove="beforeRemove"
          :on-success="handleUploadSuccess"
          :on-progress="handleUploadProgress"
          :before-upload="handleBeforeUpload"
          @update:file-list="(files) => formData.evidenceUrl = files"
        >
          <template #trigger>
            <el-button type="primary">文件上传</el-button>
          </template>
          <template #file="{ file }">
            <el-link
              v-if="file.url"
              :href="file.url"
              target="_blank"
              type="primary"
              :underline="false"
            >
              {{ file.name }}
            </el-link>
            <span v-else>{{ file.name }}</span>
            <el-button
      class="delete-icon"
      type="danger"
      link
      :icon="Delete"
      @click.stop="removeFile(file)"
    />
          </template>
          <template #tip>
            <div class="el-upload__tip text-gray-500">
              文件大小不能超过20MB（VPN模式下尽量低于5MB）
            </div>
          </template>
        </el-upload>
        <!-- AI识别按钮 -->
        <el-upload
          :show-file-list="false"
          :before-upload="beforeAIUpload"
          :http-request="handleAIUpload"
          accept="image/*,.pdf,.doc,.docx"
          style="display:inline-block;margin-left:12px;vertical-align:top;"
        >
          <el-button type="success" plain :loading="aiLoading">AI识别填表</el-button>
        </el-upload>
      </el-form-item>
      
      <!-- 软著特定字段 -->
      <el-form-item label="软著名称" prop="name">
        <el-input v-model="formData.name" placeholder="请输入软著名称" />
      </el-form-item>
      <el-form-item label="著作权编号" prop="no">
        <el-input v-model="formData.no" placeholder="请输入著作权编号" />
      </el-form-item>
      <el-form-item label="所属单位" prop="affiliation">
        <el-select v-model="formData.affiliation" placeholder="请选择所属单位">
          <el-option
            v-for="dict in getIntDictOptions(DICT_TYPE.AFFILIATION)"
            :key="dict.value"
            :label="dict.label"
            :value="dict.value"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="登记号" prop="registrationNum">
        <el-input v-model="formData.registrationNum" placeholder="请输入登记号" />
      </el-form-item>
      <el-form-item label="出版日期" prop="publicationTime">
        <el-date-picker
          v-model="formData.publicationTime"
          type="date"
          value-format="x"
          placeholder="选择出版日期"
        />
      </el-form-item>
      <el-form-item label="软著类型" prop="cscType">
        <el-select v-model="formData.cscType" placeholder="请选择软著类型">
          <el-option
            v-for="dict in getIntDictOptions(DICT_TYPE.CSC_TYPE)"
            :key="dict.value"
            :label="dict.label"
            :value="dict.value"
          />
        </el-select>
      </el-form-item>
      
      <!-- 作者列表 -->
      <el-form-item label="作者及贡献率" prop="authorList">
        <div v-for="(author, index) in formData.authorList" :key="index" class="mb-4">
          <div class="flex items-center gap-4">
            <el-input
              v-model="author.authorName"
              placeholder="请输入作者姓名"
              class="!w-240px"
            />
            <el-input-number
              v-model="author.rate"
              :min="1"
              :max="100"
              :precision="0"
              style="width: 120px;"
              placeholder="贡献率%"
            />
            <el-button
              type="danger"
              link
              :icon="Delete"
              @click="removeAuthor(index)"
              v-if="formData.authorList.length > 1"
            />
          </div>
        </div>
        <el-button type="primary" link @click="addAuthor">
          <Icon icon="ep:plus" class="mr-5px" />添加作者
        </el-button>
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
      <el-button @click="dialogVisible = false">取 消</el-button>
    </template>
  </Dialog>
</template>

<script setup lang="ts">
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
import { CscApi, CscVO } from '@/api/digital/csc'
import { getAccessToken } from '@/utils/auth'
import { ElMessageBox, ElMessage } from 'element-plus'
import { Delete } from '@element-plus/icons-vue'
import axios from 'axios'
import type { UploadRequestOptions } from 'element-plus'

/** 软著表单组件 */
defineOptions({ name: 'CscForm' })

const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗

const dialogVisible = ref(false) // 弹窗显示状态
const dialogTitle = ref('') // 弹窗标题
const formLoading = ref(false) // 表单加载状态
const formType = ref('') // 表单类型
const actionUrl = import.meta.env.VITE_BASE_URL + import.meta.env.VITE_API_URL + '/infra/file/upload'
const HEADERS = { Authorization: 'Bearer ' + getAccessToken() }

// 表单数据
const formData = ref({
  id: undefined,
  name: '',
  no: '',
  affiliation: undefined,
  registrationNum: '',
  publicationTime: undefined,
  cscType: undefined,
  evidenceUrl: [],
  authorList: [{ authorName: '', rate: 100 }],
  reserved1: '',
  reserved2: '',
  reserved3: '',
  reserved4: '',
  reserved5: '',
  remark: ''
})

// 表单验证规则
const formRules = reactive({
  name: [{ required: true, message: '软著名称不能为空', trigger: 'blur' }],
  no: [{ required: true, message: '著作权编号不能为空', trigger: 'blur' }],
  affiliation: [{ required: true, message: '所属单位不能为空', trigger: 'change' }],
  registrationNum: [{ required: true, message: '登记号不能为空', trigger: 'blur' }],
  publicationTime: [{ required: true, message: '出版日期不能为空', trigger: 'change' }],
  cscType: [{ required: true, message: '软著类型不能为空', trigger: 'change' }],
  evidenceUrl: [{ required: true, message: '佐证不能为空', trigger: 'change' }],
  authorList: [
    {
      type: 'array',
      required: true,
      validator: (rule, value, callback) => {
        if (!value || value.length === 0) {
          callback(new Error('作者不能为空'))
          return
        }

        const hasEmptyFields = value.some(
          author => !author.authorName || author.rate === undefined
        )
        if (hasEmptyFields) {
          callback(new Error('请填写完整的作者信息和贡献率'))
          return
        }

        const hasInvalidRate = value.some(
          author => author.rate < 1 || author.rate > 100
        )
        if (hasInvalidRate) {
          callback(new Error('贡献率必须在1%到100%之间'))
          return
        }

        const authorNames = value.map(author => author.authorName).filter(name => name !== '')
        const uniqueAuthorNames = new Set(authorNames)
        if (authorNames.length !== uniqueAuthorNames.size) {
          callback(new Error('作者不能重复'))
          return
        }

        const totalRate = value.reduce((sum, author) => sum + (author.rate || 0), 0)
        if (totalRate !== 100) {
          callback(new Error('贡献率总和必须等于100%'))
          return
        }
        
        callback()
      },
      trigger: 'change'
    }
  ]
})
const formRef = ref() // 表单引用

/** 打开表单弹窗 */
const open = async (type: string, id?: number) => {
  dialogVisible.value = true
  dialogTitle.value = t('action.' + type)
  formType.value = type
  resetForm()
  
  if (id) {
    formLoading.value = true
    try {
      const data = await CscApi.getCsc(id)

      // 处理证据URL
      if (data.evidenceUrl) {
        if (typeof data.evidenceUrl === 'string') {
          data.evidenceUrl = data.evidenceUrl
            .replace(/^\[|\]|\\/g, '')
            .split(',')
            .map(url => url.trim().replace(/^"|"$/g, ''))
            .filter(url => url)
            .map(url => convertUrlToFileObject(url))
        } else if (Array.isArray(data.evidenceUrl)) {
          data.evidenceUrl = data.evidenceUrl
            .filter(url => url)
            .map(url => typeof url === 'string' 
              ? convertUrlToFileObject(url) 
              : url
            )
        }
      } else {
        data.evidenceUrl = []
      }

      // 处理作者数据
      if (data.author && data.rate) {
        const authorNames = data.author.split(',').map(name => name.trim())
        const authorRates = data.rate.split(',').map(rate => {
          const num = parseInt(rate.trim())
          return isNaN(num) ? 0 : num
        })

        data.authorList = authorNames.map((name, index) => ({
          authorName: name,
          rate: authorRates[index] || 0
        }))
      } else {
        data.authorList = [{ authorName: '', rate: 100 }]
      }

      formData.value = data
    } finally {
      formLoading.value = false
    }
  }
}
defineExpose({ open }) // 暴露open方法

/** 提交表单 */
const emit = defineEmits(['success']) // 定义成功事件
const submitForm = async () => {
  // 验证表单
  await formRef.value.validate()
  
  // 提交请求
  formLoading.value = true
  try {
    // 处理作者和贡献率
    const authorNames = formData.value.authorList
      .filter(author => author.authorName)
      .map(author => author.authorName)
    const authorRates = formData.value.authorList
      .filter(author => author.authorName)
      .map(author => author.rate)

    // 处理证据URL
    const evidenceUrls = formData.value.evidenceUrl
      .filter(file => file.response || file.url)
      .map(file => file.response?.data || file.url)
    
    // 构建提交数据
    const data = {
      ...formData.value,
      evidenceUrl: evidenceUrls,
      author: authorNames.join(','),
      rate: authorRates.join(',')
    } as unknown as CscVO
    
    // 根据表单类型调用不同API
    if (formType.value === 'create') {
      await CscApi.createCsc(data)
      message.success(t('common.createSuccess'))
    } else {
      await CscApi.updateCsc(data)
      message.success(t('common.updateSuccess'))
    }
    
    dialogVisible.value = false
    emit('success')
  } finally {
    formLoading.value = false
  }
}

/** 重置表单 */
const resetForm = () => {
  formData.value = {
    id: undefined,
    name: '',
    no: '',
    affiliation: undefined,
    registrationNum: '',
    publicationTime: undefined,
    cscType: undefined,
    evidenceUrl: [],
    authorList: [{ authorName: '', rate: 100 }],
    reserved1: '',
    reserved2: '',
    reserved3: '',
    reserved4: '',
    reserved5: '',
    remark: ''
  }
  formRef.value?.resetFields()
}

/** 作者管理方法 */
const addAuthor = () => {
  formData.value.authorList.push({ authorName: '', rate: 0 })
}
const removeAuthor = (index: number) => {
  formData.value.authorList.splice(index, 1)
  if (formData.value.authorList.length === 1) {
    formData.value.authorList[0].rate = 100
  }
}

/** 文件上传方法 */
const handleUploadProgress = (event: any, uploadFile: any) => {
  uploadFile.percentage = Math.round((event.loaded / event.total) * 100)
}

const handleBeforeUpload = (file: File) => {
  const maxSize = 20 * 1024 * 1024
  if (file.size > maxSize) {
    ElMessage.error('文件大小不能超过20MB')
    return false
  }
  return true
}

const handleUploadSuccess = (response: any, uploadFile: any) => {
  if (response.code === 0) {
    uploadFile.url = response.data
    uploadFile.name = response.data.split('/').pop() || 'file'
    uploadFile.status = 'success'
    formRef.value?.clearValidate(['evidenceUrl'])
  } else {
    ElMessage.error('上传失败：' + response.msg)
    uploadFile.status = 'error'
  }
}

const handleRemove = (file: any, uploadFiles: any[]) => {
  if (uploadFiles.length === 0) {
    formRef.value?.validateField('evidenceUrl')
  }
}

const handlePreview = (uploadFile: any) => {
  window.open(uploadFile.url)
}

const beforeRemove = async (uploadFile: any) => {
  if (!uploadFile.url && uploadFile.status === 'ready') {
    return true
  }
  return await ElMessageBox.confirm(`确认删除 ${uploadFile.name} 吗?`)
}

/** URL转换文件对象 */
const convertUrlToFileObject = (url: string) => {
  if (!url) return null
  return {
    name: url.split('/').pop() || 'file',
    url: url,
    status: 'success',
    uid: Date.now() + '_' + Math.random().toString(36).slice(2)
  }
}

/** AI识别功能 */
const aiLoading = ref(false)
const beforeAIUpload = (file: File) => {
  const maxSize = 20 * 1024 * 1024
  return file.size <= maxSize
}

const handleAIUpload = async (options: UploadRequestOptions) => {
  const { file } = options
  aiLoading.value = true
  try {
    const formDataUpload = new FormData()
    formDataUpload.append('file', file)
    
    const res = await axios.post('/ai/CSC', formDataUpload, {
      baseURL: import.meta.env.VITE_BASE_URL,
      headers: { 
        'Content-Type': 'multipart/form-data',
        ...HEADERS,
        'tenant-id': '1'
      }
    })
    
    fillFormByAIResult(res.data.data || JSON.parse(res.data.msg))
    ElMessage.success('AI识别成功，表单已自动填充')
  } catch (e) {
    ElMessage.error('识别失败：' + e.message)
  } finally {
    aiLoading.value = false
  }
}

/** 填充AI识别结果 */
const fillFormByAIResult = (result: any) => {
  // 处理作者数据 - 支持单个或多个作者
  if (result.author) {
    // 分割作者名字（按空格分割并过滤空字符串）
    const authorNames = result.author
      .split(' ')
      .filter((name: string) => name.trim() !== '');
    
    // 如果有多个作者
    if (authorNames.length > 0) {
      formData.value.authorList = [];
      
      // 计算平均贡献率（整数部分）
      const baseRate = Math.floor(100 / authorNames.length);
      // 计算剩余部分（总和可能不足100）
      const remainder = 100 % authorNames.length;
      
      // 创建作者列表并分配贡献率
      authorNames.forEach((name: string, index: number) => {
        // 最后一位作者获得剩余分配
        const rate = index === authorNames.length - 1 
          ? baseRate + remainder 
          : baseRate;
        
        formData.value.authorList.push({
          authorName: name,
          rate: rate
        });
      });
    } else {
      // 如果分割失败，默认单个作者100%
      formData.value.authorList = [{
        authorName: result.author,
        rate: 100
      }];
    }
  }


  // 填充其他字段
  const fieldMap: Record<string, keyof typeof formData.value> = {
    'name': 'name',
    'no': 'no',
    'affiliation': 'affiliation',
    'registrationNum': 'registrationNum',
    'cscType': 'cscType'
  }
  
  Object.entries(fieldMap).forEach(([aiKey, formKey]) => {
    if (result[aiKey] !== undefined) {
      formData.value[formKey] = result[aiKey]
    }
  })

  // 处理日期
  if (result.publicationTime) {
    const date = new Date(result.publicationTime.replace(/-/g, '/'))
    if (!isNaN(date.getTime())) {
      formData.value.publicationTime = date.getTime()
    }
  }

  // 处理证据文件
  if (result.evidenceUrl) {
    formData.value.evidenceUrl = (Array.isArray(result.evidenceUrl) 
      ? result.evidenceUrl 
      : [result.evidenceUrl]
    ).map(url => convertUrlToFileObject(url))
  }
}

/** 自定义删除按钮功能 */
const removeFile = (file: any) => {
  // 创建新的文件列表（排除当前文件）
  const newFileList = formData.value.evidenceUrl.filter(
    item => item.uid !== file.uid
  )
  
  // 更新文件列表
  formData.value.evidenceUrl = newFileList
  
  // 触发表单验证
  formRef.value?.validateField('evidenceUrl')
}
</script>

<style scoped>
.evidence-upload {
  width: 360px;
}
</style>